package kingAI.core;

import kingAI.calc.*;
import java.io.PrintStream;

/**
 * An AI player.
 * It can choose the contract type to play and play a card.
 * Extends the abstract Player class.
 * 
 * @author Equilibrium
 * @version 1.0
 */
public class AIPlayer extends Player{
	private double noHeartsPointProbability(){
		double[] cardPossessionProbabilities;
		double totalHeartsTakenFromOtherSuits=0.0, totalHeartsGivenToOtherSuits=0.0, totalHeartsTaken=0.0;
		SingleSuitCalculator calculator;
		
		//calculation of hearts taken/given from other suits 
		//clubs
		cardPossessionProbabilities = new double[15];
		for(int i=2;i<15;i++)
			if(getHand().clubs[i])
				cardPossessionProbabilities[i]=1.0;
		calculator = new SingleSuitCalculator(cardPossessionProbabilities,CalculationType.CardsTakenFromAnotherSuit);
		calculator.calculate();
		totalHeartsTakenFromOtherSuits+=calculator.probableAmountOfTakenCards;
		totalHeartsGivenToOtherSuits+=calculator.probableAmountOfGivenCards;

		//diamonds
		cardPossessionProbabilities = new double[15];
		for(int i=2;i<15;i++)
			if(getHand().diamonds[i])
				cardPossessionProbabilities[i]=1.0;
		calculator = new SingleSuitCalculator(cardPossessionProbabilities,CalculationType.CardsTakenFromAnotherSuit);
		calculator.calculate();
		totalHeartsTakenFromOtherSuits+=calculator.probableAmountOfTakenCards;
		totalHeartsGivenToOtherSuits+=calculator.probableAmountOfGivenCards;
		
		//spades
		cardPossessionProbabilities = new double[15];
		for(int i=2;i<15;i++)
			if(getHand().spades[i])
				cardPossessionProbabilities[i]=1.0;
		calculator = new SingleSuitCalculator(cardPossessionProbabilities,CalculationType.CardsTakenFromAnotherSuit);
		calculator.calculate();
		totalHeartsTakenFromOtherSuits+=calculator.probableAmountOfTakenCards;
		totalHeartsGivenToOtherSuits+=calculator.probableAmountOfGivenCards;
		
		//calculation of hearts possession probabilities if some hearts are given during other suits
		cardPossessionProbabilities = new double[15];
		for(int i=14;i>1;i--)
			if(getHand().hearts[i])
				if(totalHeartsGivenToOtherSuits>=1.0)
					totalHeartsGivenToOtherSuits--;
				else if(totalHeartsGivenToOtherSuits>0){
					cardPossessionProbabilities[i]=1-totalHeartsGivenToOtherSuits;
					totalHeartsGivenToOtherSuits=0;
				}
				else{
					for(int j=i;j>1;j--)
						if(getHand().hearts[j])
							cardPossessionProbabilities[j]=1.0;
					break;
				}
		
		//calculation of taken hearts during other suits
		int emptyCardsAbove=14;
		while(cardPossessionProbabilities[emptyCardsAbove]==0.0 && emptyCardsAbove>1)
			emptyCardsAbove--;
		emptyCardsAbove=14-emptyCardsAbove;	
		totalHeartsTaken+=Math.min(emptyCardsAbove, totalHeartsTakenFromOtherSuits);
		
		//calculation of hearts taken during hearts
		calculator = new SingleSuitCalculator(cardPossessionProbabilities,CalculationType.CardsTakenFromThisSuit);
		calculator.calculate();
		totalHeartsTaken+=calculator.probableAmountOfTakenCards;
		
		return -30*totalHeartsTaken;
	}
	
	private double noTricksPointProbability(){		
		double[] cardPossessionProbabilities;
		SingleSuitCalculator calculator;

		
		cardPossessionProbabilities = new double[15];
		for(int i=2;i<15;i++)
			if(getHand().clubs[i])
				cardPossessionProbabilities[i]=1.0;
		calculator = new SingleSuitCalculator(cardPossessionProbabilities,CalculationType.TricksTakenFromThisSuit);
		calculator.calculate();
		System.out.println("clubs:"+calculator.probableAmountOfTakenTricks+" "+calculator.probableAmountOfGivenTricks);
		
		
		cardPossessionProbabilities = new double[15];
		for(int i=2;i<15;i++)
			if(getHand().diamonds[i])
				cardPossessionProbabilities[i]=1.0;
		calculator = new SingleSuitCalculator(cardPossessionProbabilities,CalculationType.TricksTakenFromThisSuit);
		calculator.calculate();
		System.out.println("diamonds:"+calculator.probableAmountOfTakenTricks+" "+calculator.probableAmountOfGivenTricks);

		
		cardPossessionProbabilities = new double[15];
		for(int i=2;i<15;i++)
			if(getHand().hearts[i])
				cardPossessionProbabilities[i]=1.0;
		calculator = new SingleSuitCalculator(cardPossessionProbabilities,CalculationType.TricksTakenFromThisSuit);
		calculator.calculate();
		System.out.println("hearts:"+calculator.probableAmountOfTakenTricks+" "+calculator.probableAmountOfGivenTricks);

		
		cardPossessionProbabilities = new double[15];
		for(int i=2;i<15;i++)
			if(getHand().spades[i])
				cardPossessionProbabilities[i]=1.0;
		calculator = new SingleSuitCalculator(cardPossessionProbabilities,CalculationType.TricksTakenFromThisSuit);
		calculator.calculate();
		System.out.println("spades:"+calculator.probableAmountOfTakenTricks+" "+calculator.probableAmountOfGivenTricks);
		
		return 0;
	}
	
	//TODO: write point probability calculator for NOKING
	//TODO: write point probability calculator for NOGIRLS
	//TODO: write point probability calculator for NOLASTTWO
	//TODO: write point probability calculator for NOBOYS
	//TODO: write point probability calculator for TRUMPHEARTS
	//TODO: write point probability calculator for TRUMPSPADES
	//TODO: write point probability calculator for TRUMPDIAMONDS
	//TODO: write point probability calculator for TRUMPCLUBS
	
	/**
	 * Constructs a new AIPlayer.
	 * 
	 * @param name The name of this player.
	 */
	public AIPlayer(String name, PrintStream out){
		super(name,out);
	}
	
	//TODO: complete chooseContract for AIPlayer
	public Contract chooseContract(){
		return Contract.NoTricks;
	}
	
	//TODO: complete play for AIPlayer
	public Card play(){
		return new Card(Suit.Diamonds,0);
	}
	
	//TODO: TEST; DELETE THESE
	public void TEST(){
		long time;
		out.println("Begin test...");
		out.println();
		out.println("Printing hand...");
		printHand();
		
		out.println("No hearts point probability calculator is being called...");
		time=System.currentTimeMillis();
		out.println(noHeartsPointProbability()/(-30));
		out.println("Finished in:"+(System.currentTimeMillis()-time)+"ms.");
		out.println();
		
		out.println("No tricks point probability calculator is being called...");
		time=System.currentTimeMillis();
		noTricksPointProbability();
		out.println("Finished in:"+(System.currentTimeMillis()-time)+"ms.");
	}
}
